/*
 * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved.
 *
 * encTurbo is licensed under the Mulan PSL v1.
 * You can use this software according to the terms and conditions of the Mulan PSL v1.
 * You may obtain a copy of Mulan PSL v1 at:
 *
 *     http://license.coscl.org.cn/MulanPSL
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR
 * FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v1 for more details.
 */

#include "va_display_drm.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <va_drm.h>

static struct {
    int index;
    const char* device_path;
} g_drmDevicePaths[] = {
    {DEV_DRI_RENDERD128, "/dev/dri/renderD128"},
    {DEV_DRI_RENDERD129, "/dev/dri/renderD129"},
    {DEV_DRI_RENDERD130, "/dev/dri/renderD130"},
    {DEV_DRI_RENDERD131, "/dev/dri/renderD131"},
    {DEV_DRI_RENDERD132, "/dev/dri/renderD132"},
    {DEV_DRI_OTHER, NULL},
};

ENCStatus DisplayDrmOpen(avcenc_context_s *enc_ctx)
{
    if (!enc_ctx) {
        ENC_ERR_PRT("enc_ctx null! \n");
        return ENC_STATUS_ERROR_CONTEXT_HANDLE;
    }
    if (enc_ctx->drm_device_path < DEV_DRI_RENDERD128 || enc_ctx->drm_device_path >= DEV_DRI_OTHER) {
        return ENC_STATUS_ERROR_INVALID_PARAMETER;
    }
    ENCStatus encStatus = ENC_STATUS_SUCCESS;
    char *device_name = NULL;
    int device_index = -1;
    VADisplay vaDpy;

    for (unsigned int i = 0; i < sizeof(g_drmDevicePaths) / sizeof(g_drmDevicePaths[0]); i++) {
        if (enc_ctx->drm_device_path == g_drmDevicePaths[i].index) {
            device_index = i;
            break;
        }
    }

    device_name = malloc(strlen(g_drmDevicePaths[device_index].device_path) + 1);
    if (!device_name) {
        ENC_ERR_PRT("malloc fail! \n");
        return ENC_STATUS_ERROR_MALLOC;
    }
    
    memcpy(device_name, g_drmDevicePaths[device_index].device_path, strlen(g_drmDevicePaths[device_index].device_path));
    enc_ctx->drm_fd = open(device_name, O_RDWR);
    if (enc_ctx->drm_fd < 0) {
        ENC_ERR_PRT("Failed to open the given device(%s)!\n", device_name);
        encStatus = ENC_STATUS_ERROR_OPEN_DISPLAY_DEVICE;
        goto END;
    }

    vaDpy = vaGetDisplayDRM(enc_ctx->drm_fd);
    if (!vaDpy) {
        ENC_ERR_PRT("Failed to a DRM display for the given device\n");
        close(enc_ctx->drm_fd);
        enc_ctx->drm_fd = -1; 
        encStatus = ENC_STATUS_ERROR_OPEN_DISPLAY_DEVICE;
        goto END;
    }
    
    enc_ctx->va_dpy = vaDpy;
    encStatus = ENC_STATUS_SUCCESS;

END:
    free(device_name);
    device_name = NULL;
    return encStatus;
}

ENCStatus DisplayDrmClose(avcenc_context_s *enc_ctx)
{
    if (enc_ctx->va_dpy) {
        ENC_ERR_PRT("va_dpy is not null!\n");
        return ENC_STATUS_ERROR_OPEN_DISPLAY_DEVICE;
    }

    if (enc_ctx->drm_fd > 0) {
        close(enc_ctx->drm_fd);
        enc_ctx->drm_fd = -1;
    }

    return ENC_STATUS_SUCCESS;
}

